#include <iostream>
#include <filesystem>
#include <boost/asio.hpp>
#include "common/config.hpp"
#include "common/logger.hpp"
#include "core/game_server.hpp"
#include "service/user_service.hpp"
#include "protocols/login_protocol.hpp"
#include "protocols/ping_protocol.hpp"
#include "protocols/register_user_protocol.hpp"
#include "core/di_container.hpp"
#include "storage/user_storage.hpp"
// #include "storage/mysql_user_storage.hpp"
#include "storage/mem_user_storage.hpp"
#include "common/database/mysql_manager.hpp"
#include "common/database/redis_manager.hpp"

std::string get_exe_path(int argc, char** argv) {
    // 获取可执行文件的路径
    std::filesystem::path exePath = std::filesystem::absolute(std::filesystem::path(argv[0]));
    return exePath.parent_path().string(); // 返回可执行文件的目录
}

std::string get_config_path(int argc, char** argv) {
    std::string exe_path = get_exe_path(argc, argv);
    return exe_path + "/config.json";
}

// 注册mysql和redis连接池
void register_mysql_and_redis() {
    DIContainer::register_factory<MysqlManager>([]() -> std::shared_ptr<MysqlManager> {
        auto& config = Config::get_instance();

        auto mysql_config = MySQLConfig{    
            config.get_mysql_host(),
            config.get_mysql_port(),
            config.get_mysql_user(),
            config.get_mysql_password(),
            config.get_mysql_database(),
            ConnectionPoolConfig{
                config.get_mysql_pool_initial_size(),
                config.get_mysql_pool_max_size(),
                config.get_mysql_pool_max_idle_time(),
                config.get_mysql_pool_connection_timeout()
            }
        };

        Logger::info("mysql_config: {}", mysql_config.host);
        return std::make_shared<MysqlManager>(mysql_config);
    });
    
    DIContainer::register_factory<RedisManager>([]() -> std::shared_ptr<RedisManager> {
        auto& config = Config::get_instance();
        auto redis_config = RedisConfig{
            config.get_redis_host(),
            config.get_redis_port(),
            "",  // 密码    
            0,  // 数据库
            ConnectionPoolConfig{
                config.get_redis_pool_initial_size(),
                config.get_redis_pool_max_size(),
                config.get_redis_pool_max_idle_time(),
                config.get_redis_pool_connection_timeout()
            }
        };
        Logger::info("redis_config: {}", redis_config.host);
        return std::make_shared<RedisManager>(redis_config);
    });
}

// 注册存储
void register_storage() {
    DIContainer::register_factory<storage::IUserStorage>([]() -> std::shared_ptr<storage::IUserStorage> {
        return std::make_shared<storage::MemUserStorage>();
    });
}

// 注册服务
void register_services() {
    DIContainer::register_factory<service::UserService>();
}

// 注册协议
void register_protocols(GameServer& server) {
    // message_handler.register_protocol("register", std::make_shared<protocols::RegisterProtocol>(user_service));
    server.register_protocol("ping", std::make_shared<protocols::PingProtocol>());
    // server.register_protocol("login", std::make_shared<protocols::LoginProtocol>());
    // server.register_protocol("register", std::make_shared<protocols::UserRegisterProtocol>());
    server.register_protocol("login", std::make_shared<protocols::LoginProtocol>());
    server.register_protocol("register_user", std::make_shared<protocols::RegisterUserProtocol>());
}

int main(int argc, char** argv) {
    try {
        // 初始化日志
        Logger::init();
        
        // 获取配置
        std::string exe_path = get_exe_path(argc, argv);

        // 获取配置实例
        std::string config_path = get_config_path(argc, argv);

        // 初始化配置
        Logger::info("Loading config from {}", config_path);

        // 加载配置
        Config::load_config(config_path);

        // 注册mysql和redis连接池
        Logger::info("Registering mysql and redis connection pools");
        register_mysql_and_redis();

        // 注册存储
        Logger::info("Registering storage");
        register_storage();

        // 注册服务
        Logger::info("Registering services");
        register_services();

        // 获取配置实例
        auto& config = Config::get_instance();
        
        // 创建IO上下文
        boost::asio::io_context io_context;
        
        // 创建游戏服务器
        Logger::info("Creating game server");
        GameServer server(
            io_context,
            config.get_server_address(),
            config.get_server_port()
        );

        // 注册协议
        Logger::info("Registering protocols");
        register_protocols(server);
        
        // 启动服务器
        Logger::info("Starting server");
        server.start();
        Logger::info("Server started on {}:{}", 
            config.get_server_address(),
            config.get_server_port()
        );
        
        // 运行IO上下文
        io_context.run();
        
    } catch (const std::exception& e) {
        Logger::error("Exception: {}", e.what());
        return 1;
    }
    
    return 0;
}